package com.ruoyi.xdata.service.impl;

import java.io.File;
import java.util.List;

import cn.hutool.core.util.XmlUtil;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.xdata.mapper.XdataKettleMapper;
import com.ruoyi.xdata.domain.XdataKettle;
import com.ruoyi.xdata.service.IXdataKettleService;
import org.springframework.transaction.annotation.Transactional;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

/**
 * 同步任务Service业务层处理
 * 
 * @author yepanpan
 * @date 2025-02-14
 */
@Service
public class XdataKettleServiceImpl implements IXdataKettleService 
{
    private static final Logger log = LoggerFactory.getLogger(XdataKettleServiceImpl.class);

    @Autowired
    private XdataKettleMapper xdataKettleMapper;

    /**
     * 查询同步任务
     * 
     * @param id 同步任务主键
     * @return 同步任务
     */
    @Override
    public XdataKettle selectXdataKettleById(Long id)
    {
        return xdataKettleMapper.selectXdataKettleById(id);
    }

    /**
     * 查询同步任务列表
     * 
     * @param xdataKettle 同步任务
     * @return 同步任务
     */
    @Override
    public List<XdataKettle> selectXdataKettleList(XdataKettle xdataKettle)
    {
        return xdataKettleMapper.selectXdataKettleList(xdataKettle);
    }

    /**
     * 新增同步任务
     * 
     * @param xdataKettle 同步任务
     * @return 结果
     */
    @Override
    @Transactional
    public int insertXdataKettle(XdataKettle xdataKettle)
    {
        xdataKettle.setCreateTime(DateUtils.getNowDate());
        int ret = xdataKettleMapper.insertXdataKettle(xdataKettle);
        checkKettleFile(xdataKettle);
        xdataKettleMapper.updateXdataKettle(xdataKettle);
        return ret;
    }

    /**
     * 验证kettle文件是否有效
     * @param xdataKettle
     */
    private void checkKettleFile(XdataKettle xdataKettle){
        if(xdataKettle.getKettleFile().startsWith(XdataKettle.FOLDER)){
            return;
        }
        if(xdataKettle.getType().equals(XdataKettle.TYPE_KTR)){
            checkKettleKtr(xdataKettle);
        }else if(xdataKettle.getType().equals(XdataKettle.TYPE_KJB)){
            checkKettleKJb(xdataKettle);;
        }
    }
    /**
     * 验证kettle的ktr文件是否有效
     * @param xdataKettle
     */
    private void checkKettleKtr(XdataKettle xdataKettle){
        String filePath = RuoYiConfig.getProfile()+"/"+xdataKettle.getKettleFile().substring(Constants.RESOURCE_PREFIX.length());

        //验证文件类型
        String ext = filePath.substring(filePath.lastIndexOf('.')+1).toLowerCase();
        if(!ext.equalsIgnoreCase(XdataKettle.TYPE_KTR)){
            throw new ServiceException("无效的Kettle文件");
        }

        //判断 文件是否有效
        File kettleFile = new File(filePath);
        if(!kettleFile.exists()){
            throw new ServiceException("Kettle文件不存在");
        }else if(kettleFile.length() == 0){
            throw new ServiceException("Kettle文件不能为空");
        }

        //转换到kettle目录
        File kettleFolder = new File(RuoYiConfig.getProfile()+XdataKettle.FOLDER+xdataKettle.getId());
        if(!kettleFolder.exists()){
            kettleFolder.mkdirs();
        }

        //如果是转换，就将文件转移到Kettle目录
        filePath = XdataKettle.FOLDER+xdataKettle.getId()+"/"+ kettleFile.getName();
        kettleFile.renameTo(new File(RuoYiConfig.getProfile()+filePath));
        xdataKettle.setJobFile(filePath);
    }

    /**
     * 验证kettle的kjb文件是否有效
     * @param xdataKettle
     */
    private void checkKettleKJb(XdataKettle xdataKettle){
        String baseFolder = XdataKettle.FOLDER+xdataKettle.getId()+"/";
        //创建kettle目录
        File kettleFolder = new File(RuoYiConfig.getProfile()+baseFolder);
        if(!kettleFolder.exists()){
            kettleFolder.mkdirs();
        }

        String[] fs = xdataKettle.getKettleFile().split(",");
        File kjb = null;
        Document xml = null;
        for(String filePath:fs){

            log.info("kettle file {} ", filePath);

            File kettleFile = new File(RuoYiConfig.getProfile()+"/"+filePath.substring(Constants.RESOURCE_PREFIX.length()));
            if(!kettleFile.exists()){
                throw new ServiceException("Kettle文件不存在:"+kettleFile.getName());
            }else if(kettleFile.length() == 0){
                throw new ServiceException("Kettle文件不能为空:"+kettleFile.getName());
            }
            //按文件类型转换
            String ext = filePath.substring(filePath.lastIndexOf('.')+1).toLowerCase();
            if(ext.equalsIgnoreCase(XdataKettle.TYPE_KJB)){
                filePath = baseFolder+ kettleFile.getName();
                kjb = new File(RuoYiConfig.getProfile()+filePath);
                kettleFile.renameTo(kjb);
                xdataKettle.setJobFile(filePath);
            }else if(ext.equalsIgnoreCase(XdataKettle.TYPE_KTR)){
                filePath = baseFolder+ kettleFile.getName();
                kettleFile.renameTo(new File(RuoYiConfig.getProfile()+filePath));
            }else{
                throw new ServiceException("无效的Kettle文件："+kettleFile.getName());
            }
        }

        xml = XmlUtil.readXML(kjb);
        NodeList list = xml.getElementsByTagName("filename");
        if(list == null || list.getLength() == 0){
            return;
        }

        //替换路径
        for(int i=0;i<list.getLength();i++){
            Node node = list.item(i);
            String v = node.getTextContent();
            log.info("kettle node {}, file {}",node.toString(), v);
            if(StringUtils.isNotEmpty(v)){
                v = v.replaceAll("\\\\", "/");
                v = RuoYiConfig.getProfile()+baseFolder+v.substring(v.lastIndexOf("/")+1);
                log.info("replace {} to {}",node.getTextContent(), v);
                node.setTextContent(v);
            }
        }

        try {
            /** 将document中的内容写入文件中 */
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer();
            DOMSource source = new DOMSource(xml);
            StreamResult result = new StreamResult(kjb);
            transformer.transform(source, result);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 修改同步任务
     * 
     * @param xdataKettle 同步任务
     * @return 结果
     */
    @Override
    public int updateXdataKettle(XdataKettle xdataKettle)
    {
        checkKettleFile(xdataKettle);
        xdataKettle.setUpdateTime(DateUtils.getNowDate());
        return xdataKettleMapper.updateXdataKettle(xdataKettle);
    }

    /**
     * 批量删除同步任务
     * 
     * @param ids 需要删除的同步任务主键
     * @return 结果
     */
    @Override
    public int deleteXdataKettleByIds(Long[] ids)
    {
        return xdataKettleMapper.deleteXdataKettleByIds(ids);
    }

    /**
     * 删除同步任务信息
     * 
     * @param id 同步任务主键
     * @return 结果
     */
    @Override
    public int deleteXdataKettleById(Long id)
    {
        return xdataKettleMapper.deleteXdataKettleById(id);
    }

}
